package com.yonyou.common.bizflow.utils;


import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.yonyou.iuap.context.InvocationInfoProxy;
import com.yonyou.ucf.mdd.ext.core.AppContext;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.isvrequest.ISVRequest;
import com.yonyoucloud.iuap.ucf.mdd.starter.ucg.openapi.isv.router.module.isvrequest.ISVRequestBody;
import java.util.HashMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.http.HttpStatus;
import org.apache.http.NameValuePair;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.poi.util.StringUtil;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 通讯https工具类
 *
 * @author lizhgb
 * @date 2015-9-6l
 */
@Slf4j
public class HttpClientUtil_1 {

  private static ISVRequest isvRequest = AppContext.getBean(ISVRequest.class);

  public static final String YHT_ACCESS_TOKEN = "yht_access_token";

  private static final String DEFAULT_CHARSET_UTF8 = "UTF-8";
  private static final String DEFAULT_CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";
  private static final String DEFAULT_CONTENT_TYPE_JSON = "application/json";
  private static final int MAX_TIMEOUT = 30000;
  private static final int MAX_RETRY_TIMES = 5;
  private static final int MAX_THREAD_TOTAL = 50;


  public static List<NameValuePair> getParams(HttpServletRequest request) {

    List<NameValuePair> params = new ArrayList<>();
    Map<String, String[]> paramMap = request.getParameterMap();
    if (paramMap != null && !paramMap.isEmpty()) {
      Iterator<String> keys = paramMap.keySet().iterator();
      while (keys.hasNext()) {
        String key = keys.next();
        String[] values = paramMap.get(key);
        NameValuePair nameValuePair = new BasicNameValuePair(key, StringUtil.join(values));
        params.add(nameValuePair);
      }
    }
    return params;
  }


  /**
   * 发送https post请求
   *
   * @param action
   * @param bodyParam
   * @return
   * @throws Exception
   * @author lizhgb
   * @Date 2015-9-10 上午11:12:55
   */
  public static String httpsPost(String action, Object bodyParam) throws Exception {
    return httpsPost(action, null, bodyParam);
  }


  /**
   * 发送https post请求
   *
   * @param url
   * @param bodyParam
   * @return
   * @throws Exception
   */
  public static String httpsPostForm(String url, List<NameValuePair> bodyParam) throws Exception {
    return httpsPostForm(url, null, bodyParam);
  }


  /**
   * 发送https post请求
   *
   * @param url
   * @return
   * @throws Exception
   * @author lizhgb
   * @Date 2015-9-6 下午1:32:06
   */
  public static String httpsPostForm(String url, Map<String, String> headerParams, List<NameValuePair> bodyParams) throws Exception {

    headerParams.put("Content-Type",DEFAULT_CONTENT_TYPE_FORM);
    HashMap<String,String> params = new HashMap<>();
    String param = JSONObject.toJSONString(bodyParams);
    params.put("data",param);
    ISVRequestBody isvRequestBody = new ISVRequestBody();
    isvRequestBody.setYhtAccessToken("yht_access_token_encryption");
    isvRequestBody.setRequestMethod("POSTJSON");
    isvRequestBody.setUrl(url);
    isvRequestBody.setType("bizflow");
    isvRequestBody.setParams(params);
    isvRequestBody.setHeaders(headerParams);
    String resultStr = null;
    try (CloseableHttpResponse httpResponse = isvRequest.doCloseableHttpResponse(InvocationInfoProxy.getTenantid(),isvRequestBody)) {
      resultStr = EntityUtils.toString(httpResponse.getEntity(), "utf-8");
      int statusCode = httpResponse.getStatusLine().getStatusCode();
      if (httpResponse.getStatusLine().getStatusCode() != HttpStatus.SC_OK) {
        throw new Exception(getHttpInfoStr(statusCode, url, headerParams, bodyParams, resultStr));
      }
    } catch (IOException e) {
      throw new Exception(getHttpInfoStr(null, url, headerParams, bodyParams, resultStr));
    }
    log.info("Post请求返回：" + resultStr);
    return resultStr;
  }

  /**
   * 发送https post请求
   *
   * @param action
   * @return
   * @throws Exception
   * @author lizhgb
   * @Date 2015-9-6 下午1:32:06
   */
  public static String httpsPost(String action, Map<String, String> headerParams, Object bodyParams) throws Exception {

    HashMap<String,String> params = new HashMap<>();
    String param = JSONObject.toJSONString(bodyParams);
    params.put("data",param);
    ISVRequestBody isvRequestBody = new ISVRequestBody();
    isvRequestBody.setYhtAccessToken("yht_access_token_encryption");
    isvRequestBody.setRequestMethod("POSTJSON");
    isvRequestBody.setUrl(action);
    isvRequestBody.setType("bizflow");
    isvRequestBody.setParams(params);
    isvRequestBody.setHeaders(headerParams);
    String resultStr = null;
    try (CloseableHttpResponse response = isvRequest.doCloseableHttpResponse(InvocationInfoProxy.getTenantid(),isvRequestBody)) {
      resultStr = EntityUtils.toString(response.getEntity(), "utf-8");
      JSONObject json = JSONObject.parseObject(resultStr);
      resultStr = json.getString("data");
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode != HttpStatus.SC_OK) {
        throw new Exception(getHttpInfoStr(statusCode, action, headerParams, bodyParams, resultStr));
      }
    } catch (IOException e) {
      throw new Exception(getHttpInfoStr(null, action, headerParams, bodyParams, resultStr), e);
    }
    log.info("Post请求返回：" + resultStr);
    return resultStr;
  }


  public static String getHttpInfoStr(Integer statusCode, String url, Map<String, String> headerParam, Object bodyParams, String resultStr) {
    return "【Post请求异常】" + "status:" + statusCode + ", url:" + url + ", header:" + JSON.toJSONString(headerParam) + ", body:" + JSON.toJSONString(bodyParams) + ", result:" + resultStr;
  }

  public static String getHttpInfoStr(String url, Map<String, String> headerParams, Object bodyParams, String resultStr) {
    return getHttpInfoStr(null, url, headerParams, bodyParams, resultStr);
  }

  /**
   * 发送https get请求
   *
   * @param url
   * @return
   * @throws Exception
   * @author lizhgb
   * @Date 2015-9-7 上午9:06:57
   */
  public static String httpsGet(String url, Map<String, String> headerParams, List<NameValuePair> bodyParams) throws Exception {

    URIBuilder uriBuilder = new URIBuilder();
    if (bodyParams != null && !bodyParams.isEmpty()) {
      for (NameValuePair pair : bodyParams) {
        uriBuilder.setParameter(pair.getName(), pair.getValue());
      }
    }
    String urlWithParam = url + uriBuilder.toString();
    headerParams.put("Content-Type", DEFAULT_CONTENT_TYPE_FORM);
    ISVRequestBody isvRequestBody = new ISVRequestBody();
    isvRequestBody.setYhtAccessToken("yht_access_token_encryption");
    isvRequestBody.setRequestMethod("GET");
    isvRequestBody.setUrl(urlWithParam);
    isvRequestBody.setType("bizflow");
    StringBuilder newCookieStr = new StringBuilder();
    String cookieStr = headerParams.get("Cookie");
    if(StringUtils.isNotBlank(cookieStr)){
      newCookieStr.append(cookieStr);
      if (!cookieStr.contains(YHT_ACCESS_TOKEN)){
        newCookieStr.append(YHT_ACCESS_TOKEN).append("=").append(InvocationInfoProxy.getExtendAttribute(YHT_ACCESS_TOKEN).toString()).append(";");
      }
      headerParams.put("Cookie",newCookieStr.toString());
    }
    isvRequestBody.setHeaders(headerParams);
    String resultStr = null;
    try (CloseableHttpResponse response = isvRequest.doCloseableHttpResponse(InvocationInfoProxy.getTenantid(),isvRequestBody)) {
      resultStr = EntityUtils.toString(response.getEntity(), DEFAULT_CHARSET_UTF8);
      JSONObject json = JSONObject.parseObject(resultStr);
      resultStr = json.getString("data");
      int statusCode = response.getStatusLine().getStatusCode();
      if (statusCode != HttpStatus.SC_OK) {
        throw new Exception(getHttpInfoStr(statusCode, url, headerParams, bodyParams, resultStr));
      }
    } catch (IOException e) {
      throw new Exception(getHttpInfoStr(null, url, headerParams, bodyParams, resultStr), e);
    }
    log.info("Get请求返回：" + resultStr);
    return resultStr;
  }


  /**
   * 发送https get请求
   *
   * @param url
   * @return
   * @throws Exception
   * @author lizhgb
   * @Date 2015-9-7 上午9:06:57
   */
  public static String httpsGet(String url) throws Exception {
    return httpsGet(url, null, null);
  }


  /**
   * 发送https get请求
   *
   * @param url
   * @return
   * @throws Exception
   * @author lizhgb
   * @Date 2015-9-7 上午9:06:57
   */
  public static String httpsGet(String url, List<NameValuePair> bodyParams) throws Exception {
    return httpsGet(url, null, bodyParams);
  }

}

